package com.xueyi.workflow.util;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.xueyi.workflow.domain.dto.GraphSchema;
import java.util.*;

/**
 * FlowDesigner 流程设计器的 BPMN XML 生成器示例
 * 展示如何为新的流程设计器添加支持
 * 
 * @author xueyi
 */
public class FlowDesignerBpmnGenerator extends AbstractBpmnGenerator {
    
    private final ObjectMapper objectMapper = new ObjectMapper();
    
    @Override
    public String generateBpmnXml(GraphSchema schema, String processId, String processName) {
        // 对于标准的 GraphSchema，使用工厂中的其他生成器
        return BpmnGeneratorFactory.getGenerator(schema).generateBpmnXml(schema, processId, processName);
    }
    
    @Override
    public String generateBpmnXmlFromRawData(Object rawData, String processId, String processName) {
        try {
            // 解析 FlowDesigner 特有的数据格式
            Map<String, Object> flowData;
            if (rawData instanceof String) {
                flowData = objectMapper.readValue((String) rawData, Map.class);
            } else if (rawData instanceof Map) {
                flowData = (Map<String, Object>) rawData;
            } else {
                throw new IllegalArgumentException("不支持的数据类型: " + rawData.getClass().getSimpleName());
            }
            
            // 检查是否是 FlowDesigner 格式
            if (!isFlowDesignerFormat(flowData)) {
                throw new IllegalArgumentException("不是 FlowDesigner 格式的数据");
            }
            
            // 转换为标准 GraphSchema
            GraphSchema schema = convertToGraphSchema(rawData);
            
            // 使用标准生成器生成 XML
            return BpmnGeneratorFactory.getGenerator(schema).generateBpmnXml(schema, processId, processName);
            
        } catch (Exception e) {
            throw new RuntimeException("生成 BPMN XML 失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    public boolean supports(Object rawData) {
        if (rawData instanceof String) {
            try {
                Map<String, Object> map = objectMapper.readValue((String) rawData, Map.class);
                return isFlowDesignerFormat(map);
            } catch (Exception e) {
                return false;
            }
        } else if (rawData instanceof Map) {
            return isFlowDesignerFormat((Map<String, Object>) rawData);
        }
        return false;
    }
    
    @Override
    public GraphSchema convertToGraphSchema(Object rawData) {
        try {
            // 将 FlowDesigner 数据转换为标准的 GraphSchema
            Map<String, Object> flowData;
            if (rawData instanceof String) {
                flowData = objectMapper.readValue((String) rawData, Map.class);
            } else if (rawData instanceof Map) {
                flowData = (Map<String, Object>) rawData;
            } else {
                throw new IllegalArgumentException("不支持的数据类型: " + rawData.getClass().getSimpleName());
            }
            
            GraphSchema schema = new GraphSchema();
            
            // 转换节点（FlowDesigner 可能使用不同的字段名）
            List<Map<String, Object>> flowNodes = (List<Map<String, Object>>) flowData.get("flowNodes");
            if (flowNodes != null) {
                List<GraphSchema.FlowNode> nodes = new ArrayList<>();
                for (Map<String, Object> flowNode : flowNodes) {
                    nodes.add(convertFlowNodeToFlowNode(flowNode));
                }
                schema.setNodes(nodes);
            }
            
            // 转换连线（FlowDesigner 可能使用不同的字段名）
            List<Map<String, Object>> flowConnections = (List<Map<String, Object>>) flowData.get("flowConnections");
            if (flowConnections != null) {
                List<GraphSchema.FlowEdge> edges = new ArrayList<>();
                for (Map<String, Object> flowConnection : flowConnections) {
                    edges.add(convertFlowConnectionToFlowEdge(flowConnection));
                }
                schema.setEdges(edges);
            }
            
            return schema;
            
        } catch (Exception e) {
            throw new RuntimeException("转换为 GraphSchema 失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 检查是否是 FlowDesigner 格式
     */
    private boolean isFlowDesignerFormat(Map<String, Object> data) {
        // FlowDesigner 特有的标识字段
        return data.containsKey("flowNodes") && 
               data.containsKey("flowConnections") && 
               data.containsKey("designerType") && 
               "FlowDesigner".equals(data.get("designerType"));
    }
    
    /**
     * 将 FlowDesigner 节点转换为标准 FlowNode
     */
    private GraphSchema.FlowNode convertFlowNodeToFlowNode(Map<String, Object> flowNode) {
        GraphSchema.FlowNode node = new GraphSchema.FlowNode();
        
        // 字段映射：FlowDesigner 使用不同的字段名
        node.setId((String) flowNode.get("nodeId"));
        node.setType((String) flowNode.get("nodeType"));
        
        // 转换 data 字段
        Map<String, Object> nodeData = new HashMap<>();
        nodeData.put("label", flowNode.get("nodeName"));
        nodeData.put("assignees", flowNode.get("assignees"));
        nodeData.put("cc", flowNode.get("ccUsers"));
        nodeData.put("notifyMethods", flowNode.get("notificationMethods"));
        
        node.setData(nodeData);
        
        return node;
    }
    
    /**
     * 将 FlowDesigner 连线转换为标准 FlowEdge
     */
    private GraphSchema.FlowEdge convertFlowConnectionToFlowEdge(Map<String, Object> flowConnection) {
        GraphSchema.FlowEdge edge = new GraphSchema.FlowEdge();
        
        // 字段映射：FlowDesigner 使用不同的字段名
        edge.setSource((String) flowConnection.get("fromNode"));
        edge.setTarget((String) flowConnection.get("toNode"));
        
        return edge;
    }
}
